﻿using nRoute.Components.Composition;
using System;

namespace nRoute.Mapping
{
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
    public class ResolveResourceAttribute
        : ResolveResourceBaseAttribute
    {
        private bool _isNullable;

        public ResolveResourceAttribute() { }

        public ResolveResourceAttribute(Type resourceType) 
            : this(resourceType, null) { }

        public ResolveResourceAttribute(string resourceName)
            : this(null, resourceName) { }

        public ResolveResourceAttribute(Type resourceType, string resourceName) 
            : base(resourceType, resourceName) { }

#region Properties

        public bool IsNullable
        {
            get { return _isNullable; }
            set { _isNullable = value; }
        }

#endregion

#region Override

        protected override Object ResolveResource(Type targetType, ITypeBuilder typeBuilder)
        {
            return GetResourceInstance(base.ResourceType ?? targetType, typeBuilder);
        }

#endregion

#region Helper

        protected virtual Object GetResourceInstance(Type resourceType, ITypeBuilder typeBuilder)
        {
            if (!IsNullable)
            {
                return string.IsNullOrEmpty(this.ResourceName) ? typeBuilder.ResourceCatalog.GetResource(resourceType)
                       : typeBuilder.ResourceCatalog.GetResource(resourceType, base.ResourceName);    
            }
            else
            {
                var _resourceInstance = default(Object);
                if (string.IsNullOrEmpty(this.ResourceName))
                {
                    if (typeBuilder.ResourceCatalog.TryGetResource(resourceType, out _resourceInstance))
                    {
                        return _resourceInstance;
                    }
                }
                else
                {
                    if (typeBuilder.ResourceCatalog.TryGetResource(resourceType, this.ResourceName, out _resourceInstance))
                    {
                        return _resourceInstance;
                    }
                }

                return null;
            }
        }

#endregion

    }
}